package com.liting.uitest.imgutils;

import com.liting.uitest.model.Circle;
import com.liting.uitest.model.ImagePixel;
import com.liting.uitest.model.Rectangle;
import com.liting.uitest.model.VSExecutorResult;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Mat;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 垂直对称性多线程
 */
@Slf4j
@Service
public class VerticaSymmetryExcecutor {

    @Async("asyncExecutor")
    public CompletableFuture<VSExecutorResult> vsCalc(Mat grayMat, int width, int beginHeight, int endHeight,
                                                      List<Rectangle> rectList, List<Circle> cirList) {
        int allArea = 0, sameArea = 0;
        List<ImagePixel> allPixel = new ArrayList<>();

        for (int row = beginHeight; row < endHeight; row++) {
            for (int col = 0; col < width; col++) {
                if (isInclude(col, row, rectList, cirList)) {
                    //是元素内的点

                    if (col < width / 2) {
                        allArea++;
                        ImagePixel temp = new ImagePixel(col, row);
                        allPixel.add(temp);

                        //左边的点,判断对称点的灰度值是否相同

                        Double leftPixel = OpenCVImageUtils.getGrayPixelByCoord(grayMat, col, row);
                        Double leftSymPixel = OpenCVImageUtils.getGrayPixelByCoord(grayMat, width - col, row);
                        if (leftPixel == null) leftPixel = (double) 0;
                        if (leftSymPixel == null) leftSymPixel = (double) 0;
                        if (Math.abs(leftPixel - leftSymPixel) < VSExecutorResult.ChaYi) {
                            sameArea++;
                        }
                    } else {
                        //右边的点，判断是否已经存在allPixel
                        if (notExist(width - col, row, allPixel)) {
                            allArea++;
                            ImagePixel temp = new ImagePixel(col, row);
                            allPixel.add(temp);
                        }
                    }
                } else {
                    //不是元素内的点，不处理
                    continue;
                }

            }
        }
        VSExecutorResult result = new VSExecutorResult(allArea, sameArea);
        log.info(beginHeight + "-" + endHeight + " rows  over!");

        return CompletableFuture.completedFuture(result);


    }

    private boolean notExist(int col, int row, List<ImagePixel> allPixel) {
        for (ImagePixel imagePixel : allPixel) {
            if ((col == imagePixel.getX()) && (row == imagePixel.getY())) {
                return false;
            }
        }
        return true;
    }

    private boolean isInclude(int x, int y, List<Rectangle> rectList, List<Circle> cirList) {

        for (Rectangle rectangle : rectList) {
            if (rectangle.isInclude(x, y)) {
                return true;
            }
        }

        for (Circle circle : cirList) {
            if (circle.isInclude(x, y)) {
                return true;
            }
        }

        return false;
    }

}
